#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>

#define SYNC_SIG SIGUSR1

static void handler(int sig)
{
}

int main(int argc, char *argv[])
{
  pid_t child_pid;
  sigset_t block_mask, orig_mask, empty_mask;
  struct sigaction sa;

  setbuf(stdout, NULL);

  sigemptyset(&block_mask);
  sigaddset(&block_mask, SYNC_SIG);
  if (sigprocmask(SIG_BLOCK, &block_mask, &orig_mask) == -1)
    printf("Failed to sigprocmask\n");
  
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = SA_RESTART;
  sa.sa_handler = handler;
  if (sigaction(SYNC_SIG, &sa, NULL) == -1)
    printf("Failed to sigaction\n");

  switch (child_pid = fork()) {
  case -1:
    printf("Failed to fork\n");
  case 0:
    printf("[%d] Child started - doing some work\n",getpid());
    sleep(2);
    printf("[%d] Child about to signal parent\n",getpid());
    if (kill(getppid(), SYNC_SIG) == -1)
      printf("Failed to send signal\n");
    _exit(EXIT_SUCCESS);
    
  default:
    printf("[%d] Parent about to wait for signal\n",getpid());
    sigemptyset(&empty_mask);
    if (sigsuspend(&empty_mask) == -1 && errno != EINTR)
      printf("Failed to sigsuspend\n");
    printf("[%d] Parent got signal\n", getpid());
    if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) == -1)
      printf("Failed to sigprocmask\n");
    exit(EXIT_SUCCESS);
  }
}
